package com.h3c.nem.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.h3c.nem.dto.TbFlowInstDTO;
import com.h3c.nem.dto.enums.TodoTaskNodeEnum;
import com.h3c.nem.entity.SdAllWorker;
import com.h3c.nem.entity.SdTodoTask;
import com.h3c.nem.entity.TbFlowInst;
import com.h3c.nem.enums.OfferModifyApprovalEnum;
import com.h3c.nem.mapper.SdTodoTaskMapper;
import com.h3c.nem.service.CommService;
import com.h3c.nem.service.ISdTodoTaskService;
import com.h3c.nem.utils.AppBusinessException;
import com.h3c.nem.utils.BusiEnumDefine;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

/**
 * Copyright (C), 2020-2020, h3c
 * FileName: SdTodoTaskServiceImpl
 *
 * @Author: l22886
 * @Date: 2022-01-19
 * Description: sd_todo_task serviceImpl
 * Version: 1.0
 */
@Slf4j
@Service
public class SdTodoTaskServiceImpl extends ServiceImpl<SdTodoTaskMapper, SdTodoTask> implements ISdTodoTaskService {

    @Resource
    private SdTodoTaskMapper sdTodoTaskMapper;

    @Autowired
    private CommService commService;


    @Value("${todotask.sysid}")
    private String todoTaskSysId;
    @Value("${todotask.syspwd}")
    private String todoTaskSysPwd;
    @Value("${todotask.url}")
    private String toDoUrl;
    //pc端打开统一审批平台url
    @Value("${todopcurl}")
    String todoConfigPageUrl;
    //pc端打开系统url
    @Value("${todotask.pc.url}")
    String todoPcUrl;

    private static final String systemId = "HR_NEM";

    @Override
    public void sendTodoTask(SdTodoTask dto) {
        //        String loginUserDomainAccount = getLoginDomainAccount();
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(dto);
        try {
            RestTemplate restTemplate = new RestTemplate();
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.APPLICATION_JSON);
            httpHeaders.set("sysid", todoTaskSysId);
            httpHeaders.set("syspwd", todoTaskSysPwd);
//            httpHeaders.set("userId",getLoginDomainAccount());
            httpHeaders.set("userId", jsonObject.getString("adduserid"));
            HttpEntity<JSONObject> requestEntity = new HttpEntity<JSONObject>(jsonObject, httpHeaders);
            ResponseEntity<String> responseJSONObject = restTemplate.exchange(toDoUrl, HttpMethod.POST, requestEntity, String.class);
            Object success = JSONObject.parseObject(responseJSONObject.getBody()).get("success");
            log.info(success + "==============================================================");
            log.info(responseJSONObject.toString());
            if (success.equals(false)) {
                throw new AppBusinessException("发送待办至队列失败");
            }
        } catch (Exception e) {
            System.out.println("发送待办至队列失败");
            e.printStackTrace();
            throw new AppBusinessException("发送待办至队列失败");
        }
    }

    @Override
    public SdTodoTask createOfferModifyTodoTask(String approvalUserIds, OfferModifyApprovalEnum approvalEnum,
                                                String flowId, String processId, String subject, String bpUserId,
                                                String bpUserName) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String accounts = "";
        String names = "";
        if (!StringUtils.isEmpty(approvalUserIds)) {
            //通过当前处理人查出当前处理人AllWorker
            SdAllWorker sdAllWorker = commService.getAllWorkerDoFromLocalCache(approvalUserIds);
            accounts = sdAllWorker.getDomainAccount();
            log.info("当前处理人" + accounts);
            names = sdAllWorker.getWorkerName();
        }
        String acceptType = BusiEnumDefine.TODO_ACCEPT_PC_MOBILE;

        SdTodoTask one = getOne(new QueryWrapper<SdTodoTask>().eq("systemid", systemId).eq("processid", processId).eq("docunid", flowId));
        String bpUserAccount = "";
        if (!StringUtils.isEmpty(bpUserId)) {
            //通过当前处理人查出当前处理人AllWorker
            SdAllWorker sdAllWorker = commService.getAllWorkerDoFromLocalCache(bpUserId);
            bpUserAccount = sdAllWorker.getDomainAccount();
        }

        SdTodoTask task = new SdTodoTask();
        task.setSystemid(systemId);
        task.setSubject(subject); //修改offer信息申请
        task.setAccepttype(acceptType);
        task.setAdduserid(bpUserAccount);
        task.setAddusername(bpUserName);
        task.setAppid(null);
        task.setApplytime(dateFormat.format(new Date()));
        task.setAssigner("");
        task.setStatus(approvalEnum.getTodoStatus());
        task.setAuthorid(accounts);
        task.setAuthorname(names);
        task.setTimestamp(dateFormat.format(new Date()));
        task.setMaildaily(null);

        OfferModifyApprovalEnum nextNode = OfferModifyApprovalEnum.getNextNodeId(approvalEnum.getNodeId());
        String pcUrl = ""; //拼接移动中台地址
        if (nextNode != null) {
            pcUrl = todoConfigPageUrl + "currentNodeId=" + nextNode.getNodeId() + "&docId=" + flowId
                    + "&systemId=" + systemId + "&workFlowId=" + processId;
            task.setNodename(nextNode.getNodeName());
            task.setNodeid(nextNode.getNodeId());
        } else {
            //结束,当前节点
            pcUrl = todoConfigPageUrl + "currentNodeId=" + approvalEnum.getNodeId() + "&docId=" + flowId
                    + "&systemId=" + systemId + "&workFlowId=" + processId;
            task.setNodename(approvalEnum.getNodeName());
            task.setNodeid(approvalEnum.getNodeId());
        }
        task.setProcessid(processId); //N7
        task.setProcessname("预备员工offer信息修改审核");
        task.setRedirecturl("");
        //能否批量处理（1是\0否）
        task.setIsbatch("0");
        task.setDocunid(flowId);
        task.setTodopcurl(pcUrl);
        //解决邮催待办url无法审批，带来的问题是查看已办打不开
        task.setUrl(pcUrl);
        task.setIspcdetail(BusiEnumDefine.TODO_PCDETAIL_NO);

        if (one == null) {
            task.setEnduserid("");
            log.info("新建待办：systemId={}, processId={}, docunId={}", systemId, processId, flowId);
            save(task);
        } else {
            getEndUserId(one);
            log.info("更新待办：systemId={}, processId={}, docunId={}", systemId, processId, flowId);
            UpdateWrapper<SdTodoTask> updateWrapper = new UpdateWrapper<SdTodoTask>()
                    .eq("systemid", systemId).eq("processid", processId).eq("docunid", flowId);
            update(task, updateWrapper);
        }
        return task;
    }

    public void getEndUserId(SdTodoTask todoTask) {
        String endUserid = todoTask.getEnduserid();
        String authorId = todoTask.getAuthorid();
        if (!endUserid.contains(authorId)) {
            String accountId = "";
            if (!StringUtils.isEmpty(endUserid)) {
                accountId = endUserid + ",";
            }
            todoTask.setEnduserid(accountId + authorId);
        }
    }

    @Override
    public void updateTodoTask(SdTodoTask todoTask) {
        QueryWrapper<SdTodoTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SdTodoTask::getSystemid, systemId)
                .eq(SdTodoTask::getProcessid, todoTask.getProcessid())
                .eq(SdTodoTask::getDocunid, todoTask.getDocunid());
        update(todoTask, queryWrapper);
    }

    @Override
    public SdTodoTask getTodoTask(String processId, String flowId) {
        QueryWrapper<SdTodoTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SdTodoTask::getSystemid, systemId)
                .eq(SdTodoTask::getProcessid, processId)
                .eq(SdTodoTask::getDocunid, flowId);
        return getOne(queryWrapper);
    }


    public void initOrUpdateTodoTask(TbFlowInst tbFlowInst) {
        initOrUpdateTodoTask(JSONObject.parseObject(JSON.toJSONString(tbFlowInst), TbFlowInstDTO.class));
    }

    public void initOrUpdateTodoTask(TbFlowInstDTO tbFlowInstDTO) {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        String approvalUserIds = tbFlowInstDTO.getApprovalUserIds();
        String accounts = "";
        String names = "";
        if (!StringUtils.isEmpty(approvalUserIds)) {
            //通过当前处理人查出当前处理人AllWorker
            SdAllWorker sdAllWorker = commService.getAllWorkerDoFromLocalCache(approvalUserIds);
            accounts = sdAllWorker.getDomainAccount();
            System.out.println("initOrUpdateTodoTask 当前处理人" + accounts);
            names = sdAllWorker.getWorkerName();
        }

        String status = tbFlowInstDTO.getFlowStatus() == BusiEnumDefine.FLOW_STATUS_FINISH ? BusiEnumDefine.PERFORMANCE_TODO_APPROVED : BusiEnumDefine.PERFORMANCE_TODO_APPROVING;

        String processId = tbFlowInstDTO.getFlowCode();
        Integer orderStatus = tbFlowInstDTO.getFlowStatus();
        SdTodoTask one = getOne(new QueryWrapper<SdTodoTask>()
                .eq("systemid", systemId)
                .eq("processid", processId)
                .eq("docunid", tbFlowInstDTO.getFlowId()));
        TodoTaskNodeEnum orderStatusEnum = TodoTaskNodeEnum.getEnumByValue(orderStatus);
        String acceptType = BusiEnumDefine.TODO_ACCEPT_PC;
        String pcUrl = null;
        if (orderStatus == BusiEnumDefine.flowStatusMonthlyPromiseExamine || orderStatus == BusiEnumDefine.flowStatusMonthlyPromiseCheck
                || orderStatus == BusiEnumDefine.flowStatusTurnFormalExamine || orderStatus == BusiEnumDefine.flowStatusTurnFormalCheck
                || orderStatus == BusiEnumDefine.flowStatusLittleTaskExamine) {
            acceptType = BusiEnumDefine.TODO_ACCEPT_PC_MOBILE;
            pcUrl = todoConfigPageUrl + "currentNodeId=" + orderStatusEnum.toString()
                    + "&docId=" + tbFlowInstDTO.getFlowId()
                    + "&systemId=" + systemId
                    + "&workFlowId=" + processId;
        }

        String workerDomainAccount = "";
        if (!StringUtils.isEmpty(tbFlowInstDTO.getWorkerId())) {
            //通过当前处理人查出当前处理人AllWorker
            SdAllWorker sdAllWorker = commService.getAllWorkerDoFromLocalCache(tbFlowInstDTO.getWorkerId());
            workerDomainAccount = sdAllWorker.getDomainAccount();
        }

        SdTodoTask task = new SdTodoTask();
        task.setSystemid(systemId);
        task.setSubject(tbFlowInstDTO.getFlowName());
        task.setAccepttype(acceptType);
        task.setAdduserid(workerDomainAccount);
        task.setAddusername(tbFlowInstDTO.getWorkerName());
        task.setAppid(null);
        task.setApplytime(sf.format(tbFlowInstDTO.getCreateTime()));
        task.setAssigner("");
        task.setStatus(status);
        task.setAuthorid(accounts);
        task.setAuthorname(names);
        StringBuilder url= new StringBuilder();
        url.append(todoPcUrl);
        Integer [] nodeIds = {11,21,31};
        if(Arrays.asList(nodeIds).contains(orderStatusEnum.getValue())){
            url.append("person/index/");
        }
        task.setUrl(url.toString());
        task.setTimestamp(sf.format(new Date()));
        task.setMaildaily(null);
        if (!(orderStatusEnum.equals(TodoTaskNodeEnum.END) || orderStatusEnum.equals(TodoTaskNodeEnum.FINISH))) {
            task.setNodename(orderStatusEnum.getName());
            task.setNodeid(orderStatusEnum.toString());
        }else {
            task.setNodename(one.getNodename());
            task.setNodeid(one.getNodeid());
        }
        task.setProcessid(processId);
        task.setProcessname(tbFlowInstDTO.getFlowName());
        task.setRedirecturl("");
        //能否批量处理（1是\0否）
        task.setIsbatch("0");
        task.setDocunid(tbFlowInstDTO.getFlowId());
        if (!StringUtils.isEmpty(pcUrl)) {
            task.setTodopcurl(pcUrl);
            //解决邮催待办url无法审批，带来的问题是查看已办打不开
            task.setUrl(pcUrl);
            task.setIspcdetail(BusiEnumDefine.TODO_PCDETAIL_NO);
        }
        if (one == null) {
            task.setEnduserid("");
            task.setSubject(generateTodoTaskSubject(task));
            System.out.println("initOrUpdateTodoTask 新建待办" + JSONObject.toJSONString(task));
            save(task);
        } else {
            //驳回到承诺制定，转正计划制定，小任务执行这三个流程的第一环节时，需要将已审批人清空，因为这些第一环节不支持审批人进入PC端页面查看；
            if(orderStatus == BusiEnumDefine.flowStatusMonthlyPromise
                    || orderStatus == BusiEnumDefine.flowStatusTurnFormalPlan
                    || orderStatus == BusiEnumDefine.flowStatusLittleTaskDoing) {
                task.setEnduserid("");
            }else{
                String endUserid = one.getEnduserid();
                String authorid = one.getAuthorid();
                if (!endUserid.contains(authorid)) {
                    String accountId = "";
                    if (!StringUtils.isEmpty(endUserid)) {
                        accountId = endUserid + ",";
                    }
                    task.setEnduserid(accountId + authorid);
                }
            }
            task.setSubject(generateTodoTaskSubject(task));
            System.out.println("initOrUpdateTodoTask 更新待办" + JSONObject.toJSONString(task));
            update(task, new UpdateWrapper<SdTodoTask>()
                    .eq("systemid", systemId)
                    .eq("processid", processId)
                    .eq("docunid", tbFlowInstDTO.getFlowId()));
        }
        sendTodoTask(task);
    }

    public String generateTodoTaskSubject(SdTodoTask todoTaskDO){
        String nodeid = todoTaskDO.getNodeid();
        String subjectName = todoTaskDO.getSubject();

        if(nodeid.equals(TodoTaskNodeEnum.MONTH_WORK_PROMISE.toString())){
            if(subjectName.startsWith("第")){
                subjectName = subjectName.substring(0,3)+"月度承诺填写流程";
            }else{
                subjectName = "第1次月度承诺填写流程";
            }
        }else if(nodeid.equals(TodoTaskNodeEnum.REGULARIZATION_PLAN.toString())){
           subjectName = "转正计划填写流程";
        }
        return subjectName;
    }

}
